package org.candan.spider.task.spider;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.candan.spider.util.SLog;
import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.filters.NodeClassFilter;
import org.htmlparser.filters.OrFilter;
import org.htmlparser.tags.ImageTag;
import org.htmlparser.tags.InputTag;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.tags.SelectTag;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;


public class TagFilter {
	private Logger logger = new SLog("TagFilter").getLogger();
	private int conNum=0;
	/**
	 * @param url
	 * @param tagsStr
	 * @param keywords ： 目前支持 <a>、<img>标签
	 * @return
	 */
	public Map<String,String> extractTag(String url, String tagsStr, String... keywords){
		logger.info("解析："+url);
		Map<String,String> result = new HashMap<String, String>();
		try {
			Parser parser = new Parser(url);
			NodeList list = parser.extractAllNodesThatMatch(createOrFilter(tagsStr));
			String urlLink = "";
			String urlName = "";
			for (int i = 0; i < list.size(); i++) {
				Node tag = list.elementAt(i);
				if (tag instanceof LinkTag){// <a> 标签
					LinkTag link = (LinkTag) tag;
					urlLink = link.getLink();
					urlName = link.getLinkText();
				}else if(tag instanceof ImageTag){ //<img>
					ImageTag image = (ImageTag) tag;
					urlLink = image.getImageURL();
					urlName = getUrlName(urlLink);
				}
//				else if()
				if(containKeywords(urlName, keywords)){
					result.put(urlName,  urlLink);
				}
			}
		} catch (ParserException e) {
			if(++conNum <=20){
				logger.error("连接出错："+e.getMessage()+"; 进入第" + conNum+" 次连接！ 共尝试 20 次连接");
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e1) {}
				extractTag(  url,   tagsStr,   keywords);
			  }else{
		          e.printStackTrace();
		          conNum = 1;
		          logger.info("连接失败"); 
		          return null;
			  }
		}
//		parser.setEncoding("gb2312");
		return result;
	}
	
	private String getUrlName(String url){
		return url.substring(url.lastIndexOf("/")+1);
	}
	/**
	 * @param tagsStr
	 * @return
	 */
	private OrFilter createOrFilter(String tagsStr){
		List<NodeFilter>  filters = new LinkedList<NodeFilter>();
		for(String str : tagsStr.replace("，",",").split(",")){
			if(str.trim().equalsIgnoreCase("a")){
				filters.add(new NodeClassFilter(LinkTag.class));
			}else if(str.trim().equalsIgnoreCase("img")){
				filters.add(new NodeClassFilter(ImageTag.class));
			}
//			else if(str.trim().equalsIgnoreCase("select")){
//				filters.add(new NodeClassFilter(SelectTag.class));
//			}else if(str.trim().equalsIgnoreCase("input")){
//				filters.add(new NodeClassFilter(InputTag.class));
//			}
		}
		return new OrFilter(filters.toArray(new NodeFilter[0]));
	}
	
	/**
	 * @category 检查是否包含关键字
	 * @param tag
	 * @param keywords
	 * @return
	 */
	public boolean containKeywords(String tag, String... keywords){
		if(keywords == null || keywords.length ==0)return true;
		for(String str: keywords){
			if(!tag.toLowerCase().contains(str.toLowerCase()))return false;
		}
		return true;
	}
	
	public static void main(String[] str){
		new TagFilter().extractTag("http://localhost:8080/test/test.html", "a,img", null);
	}
}
